/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "audio_interface_lib_capture.h"
#include "hdf_log.h"

/* virtual mixer device */
#define AUDIODRV_CTL_CAPTUREELEM_IFACE_MIXER ((int32_t)2)
#define AUDIODRV_CTL_ELEM_IFACE_ADC 1
#define AUDIODRV_CTL_ELEM_IFACE_SELECT 5
#define AUDIO_REPLY_EXTEND 16
#define AUDIO_SIZE_FRAME_16K (16 * 1024)


static int32_t DoCtlCaptureSetPauseStu(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureGetVolume(const struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureSetVolume(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureSetMuteStu(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureGetMuteStu(const struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureSetGainStu(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureGetGainStu(const struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureSceneSelect(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureGetGainThreshold(const struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoCtlCaptureGetVolThreshold(const struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t HandleCtlCaptureCmd(struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
{
    int32_t ret;

    switch (cmdId) {
        /* setPara: */
        case AUDIODRV_CTL_IOCTL_ELEM_WRITE_CAPTURE:
            ret = DoCtlCaptureSetVolume(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_MUTE_WRITE_CAPTURE:
            ret = DoCtlCaptureSetMuteStu(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_MUTE_READ_CAPTURE:
            ret = DoCtlCaptureGetMuteStu(handle, cmdId, handleData);
            break;
        /* getPara: */
        case AUDIODRV_CTL_IOCTL_ELEM_READ_CAPTURE:
            ret = DoCtlCaptureGetVolume(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_GAIN_WRITE_CAPTURE:
            ret = DoCtlCaptureSetGainStu(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_GAIN_READ_CAPTURE:
            ret = DoCtlCaptureGetGainStu(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_SCENESELECT_CAPTURE:
            ret = DoCtlCaptureSceneSelect(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_CAPTURE:
            ret = DoCtlCaptureGetGainThreshold(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_CAPTURE:
            ret = DoCtlCaptureGetVolThreshold(handle, cmdId, handleData);
            break;
        default:
            HDF_LOGE("Error: Ctl Mode not support!");
            ret = HDF_FAILURE;
            break;
    }
    return ret;
}


static int32_t DoOutputCaptureHwParams(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoOutputCaptureReadFrame(struct HdfIoService *service, int cmdId, struct HdfSBuf *reply)
{
    return HDF_SUCCESS;
}


static int32_t DoOutputCaptureRead(const struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoOutputCaptureStartPrepare(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoOutputCaptureStop(const struct DevHandleCapture *handle,
    int cmdId, const struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoOutputCaptureReqMmapBuffer(struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t DoOutputCaptureGetMmapPosition(struct DevHandleCapture *handle,
    int cmdId, struct AudioHwCaptureParam *handleData)
{
    return HDF_SUCCESS;
}


static int32_t HandleOutputCaptureCmd(struct DevHandleCapture *handle, int cmdId,
                                       struct AudioHwCaptureParam *handleData)
{
    int32_t ret;
    switch (cmdId) {
        case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
            ret = DoOutputCaptureHwParams(handle, cmdId, handleData);
            break;
        case AUDIO_DRV_PCM_IOCTL_READ:
            ret = DoOutputCaptureRead(handle, cmdId, handleData);
            break;
        case AUDIO_DRV_PCM_IOCTRL_START_CAPTURE:
        case AUDIO_DRV_PCM_IOCTL_PREPARE_CAPTURE:
            ret = DoOutputCaptureStartPrepare(handle, cmdId, handleData);
            break;
        case AUDIO_DRV_PCM_IOCTRL_STOP_CAPTURE:
            ret = DoOutputCaptureStop(handle, cmdId, handleData);
            break;
        case AUDIODRV_CTL_IOCTL_PAUSE_WRITE_CAPTURE:
            ret = DoCtlCaptureSetPauseStu(handle, cmdId, handleData);
            break;
        case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE:
            ret = DoOutputCaptureReqMmapBuffer(handle, cmdId, handleData);
            break;
        case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE:
            ret = DoOutputCaptureGetMmapPosition(handle, cmdId, handleData);
            break;
        default:
            HDF_LOGE("Output Mode not support!");
            ret = HDF_FAILURE;
            break;
    }
    return ret;
}


/************************************************************************************
Exported Interface    
*************************************************************************************/

/* CreatCapture for Bind handle */
struct DevHandleCapture *AudioBindServiceCapture(const char *name)
{
    struct DevHandleCapture *handle = NULL;
    if (name == NULL) {
        HDF_LOGE("service name NULL!");
        return NULL;
    }
    handle = (struct DevHandleCapture *)calloc(1, sizeof(struct DevHandleCapture));
    if (handle == NULL) {
        HDF_LOGE("Failed to OsalMemCalloc handle");
        return NULL;
    }

    handle->object = calloc(1, 1);
    LOG_PARA_INFO("BIND SERVICE SUCCESS!");
    return handle;
}


void AudioCloseServiceCapture(const struct DevHandleCapture *handle)
{
    LOG_FUN_INFO();
    if (handle == NULL || handle->object == NULL) {
        HDF_LOGE("Capture handle or handle->object is NULL");
        return;
    }

    free(handle->object);
    free((void*)handle);
    
    return;
}


int32_t AudioInterfaceLibModeCapture(struct DevHandleCapture * const handle,
    struct AudioHwCaptureParam * const handleData, int cmdId)
{
    LOG_FUN_INFO();
    if (handle == NULL || handle->object == NULL || handleData == NULL) {
        HDF_LOGE("paras is NULL!");
        return HDF_FAILURE;
    }
    switch (cmdId) {
        case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
        case AUDIO_DRV_PCM_IOCTL_READ:
        case AUDIO_DRV_PCM_IOCTRL_START_CAPTURE:
        case AUDIO_DRV_PCM_IOCTRL_STOP_CAPTURE:
        case AUDIO_DRV_PCM_IOCTL_PREPARE_CAPTURE:
        case AUDIODRV_CTL_IOCTL_PAUSE_WRITE_CAPTURE:
        case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE:
        case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE:
            return HandleOutputCaptureCmd(handle, cmdId, handleData);
        case AUDIODRV_CTL_IOCTL_ELEM_WRITE_CAPTURE:
        case AUDIODRV_CTL_IOCTL_ELEM_READ_CAPTURE:
        case AUDIODRV_CTL_IOCTL_MUTE_WRITE_CAPTURE:
        case AUDIODRV_CTL_IOCTL_MUTE_READ_CAPTURE:
        case AUDIODRV_CTL_IOCTL_GAIN_WRITE_CAPTURE:
        case AUDIODRV_CTL_IOCTL_GAIN_READ_CAPTURE:
        case AUDIODRV_CTL_IOCTL_SCENESELECT_CAPTURE:
        case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_CAPTURE:
        case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_CAPTURE:
            return HandleCtlCaptureCmd(handle, cmdId, handleData);
        default:
            HDF_LOGE("Error: Mode Error!");
            break;
    }
    return HDF_ERR_NOT_SUPPORT;
}

